home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / qbsub10.arc / OMNI.SUB < prev    next >
Encoding:
Text File  |  1986-06-25  |  13.6 KB  |  427 lines

  1. ' OMNI.SUB -- MSDOS QuickBASIC universal subroutines        25 June 86
  2. '        by David L. Poskie     (608) 274-9560
  3. '                  7118 Raymond Rd. Madison, WI 53719
  4. ' Please run any suggestions, corrections, additions, or changes by me.
  5. ' I can be messaged on all the major Madison, WI RBBS's.
  6.  
  7. '| OMNI.SUB contains subroutines I use in virtually every other SUB file and
  8. '|  in my general programming.  All of these could reside in one or more of the
  9. '|  specialized SUB files, but then I'd forever have to be $INCLUDE'ing those
  10. '|  SUB files, and would be forced to compile too many subroutines I didn't
  11. '|  need. The bottom line is, if you use the subroutines in the SUB files
  12. '|  contained in QBSUB.ARC, ALWAYS include this one, too.
  13. '|  >>> The main program must contain the following definitions:
  14. '|            False = 0
  15. '|            True = NOT False
  16.  
  17.     '| Get Key Input Subroutines -- an interactive series:
  18.     '|    GetKeyInput -- Gets a bomb-proof file name input
  19.     '|    GetUpperCase  -- Converts alpha ASCII characters to upper case
  20.     '|    GetKeyClear -- Clears keyboard buffer & gets user response
  21.     '|      GetKeyCode --  Returns extended & ASCII code of an INKEY$
  22.     '|    GetKeyLoop  -- Gets a key from keyboard buffer 
  23.     '|    GetKeyPress -- Prompts user for keypress to continue
  24.     '| Other Subroutines:
  25.     '|      Delay -- a hardware independent delay timer      
  26.     '|    Center -- Center text via TAB and go to next line
  27.     '|    CenterStay -- Center text via TAB and stay there
  28.     '|    CenterStay -- Center text via LOCATE and stay there
  29.     '|    ClearIn -- Reverse clear screen from edges into center
  30.     '|    ClearOut -- Reverse clear screen from center to edges
  31.     '|    Sign -- Frame text set by LOCATE
  32.     '|    SignCenter -- Frame centered text on a line
  33.     '|    Glow -- Print words with first letter of each word highlighted
  34.     '|    ReadScreen -- get color attributes of a location on screen
  35.  
  36.    'GetKeyInput
  37.    ' This subroutine attempts to get a bomb-proof, echoing input. I wanted
  38.    '  it particularly to get FILENAME.EXT, but it is a good way generally to
  39.    '  keep input within bounds in windows. If desired, it accepts control
  40.    '  character input directly and uses the alias, `\' to input a <CR>, meant
  41.    '  as part of the Text$ input. It locates the cursor, prints a shaded
  42.    '  line of length, KeyMax, and then gets the input.
  43.    ' Input:
  44.    '       X = row
  45.    '       FG = text color of the hatched area
  46.    '       BG = background color of hatched area
  47.    '       MG = background color of all that's actually input         
  48.    '       KeyMax = maximum allowable input length
  49.    '       Text$ = input prompt string (destroyed in subroutine)    
  50.    ' Output:
  51.    '       Text$ = line input by user
  52.    ' Other Vars: IsExtended -- extended code flag
  53.    '         KeyCode -- ASCII code for input character
  54.    '         RelX , RelY -- relative X,Y for input line
  55.    '             HoldFG , HoldBG -- restore colors
  56. GetKeyInput:
  57.     ' Locate & print the input prompt in Text$
  58.     IF Text$ <> ""                            _
  59.        THEN Y = 40 - (LEN(Text$) + KeyMax) /2
  60.     LOCATE X , Y , 0
  61.     PRINT Text$;
  62.     ' Now throw Text$ away so we can use the variable
  63.     Text$ = ""
  64.     ' If KeyMax not set, make it a maximum input line
  65.     IF KeyMax = 0                            _
  66.        THEN KeyMax = 255
  67.     ' Make a relative X , Y of the current cursor position
  68.     RelX = CSRLIN
  69.     RelY = POS(0)
  70.     GOSUB ReadScreen
  71.     GOSUB Hatch
  72. InKey:    
  73.     ' Get character
  74.     GOSUB GetKeyCode
  75.     ' A <CR> is the only way to get out of here
  76.     IF KeyCode = 13                            _
  77.        THEN COLOR HoldFG , HoldBG :                    _
  78.         LOCATE , , 1 :                        _
  79.         RETURN
  80.     ' If not <BS>, continue processing
  81.     IF NOT(KeyCode = 8)                        _
  82.        THEN GOTO DoInKey
  83.     ' If we can't backspace, then go
  84.     IF Text$ = ""                            _
  85.        THEN SOUND 99,1 :                        _
  86.         GOTO InKey
  87.     ' Else do a destructive backspace
  88.     COLOR , BG
  89.     PRINT CHR$(176); CHR$(29); CHR$(29);
  90.     COLOR FG + 16 , MG
  91.     PRINT CHR$(95); CHR$(29);
  92.     COLOR FG
  93.     Text$ = LEFT$(Text$ , LEN(Text$) - 1)
  94. GOTO InKey
  95. DoInKey:
  96.     ' Check length
  97.     IF LEN(Text$) = KeyMax                        _
  98.        THEN SOUND 99,1 :                        _
  99.         GOTO InKey 
  100.  
  101.     ' Not extend key
  102.     IF IsExtended = False                        _
  103.        AND KeyCode > 31                        _
  104.            THEN GOTO DoStandardKey
  105.     ' If IsExtended = False, then warn & get another key
  106.     IF IsExtended = False                        _
  107.        THEN SOUND 99 , 1 :                        _
  108.         GOTO InKey
  109.     ' Not ASCII 0
  110.     IF NOT(IsExtended = False AND KeyCode = 3)            _
  111.        THEN SOUND 99,1 :                        _
  112.         GOTO InKey
  113.     IF IsExtended = True                        _
  114.        THEN KeyCode = 0 :                         _
  115.         GOTO DoControlKey
  116.  
  117.     SOUND 99 , 1
  118. GOTO InKey
  119. DoStandardKey:
  120.     ' Standard text character
  121.     IF KeyCode > 31                            _
  122.        THEN IsStd = True :                        _
  123.         PRINT CHR$(KeyCode); :                    _
  124.         COLOR  , HoldBG :                    _
  125.         Num = 32                        _
  126.        ELSE IsStd = False    
  127.     IF IsStd                            _
  128.        AND POS(0) < RelY + KeyMax                     _
  129.            THEN COLOR FG + 16 , MG :                _
  130.             Num = 95
  131.     IF IsStd                            _
  132.        THEN PRINT CHR$(Num); :                    _
  133.         COLOR FG , MG :                        _
  134.         PRINT CHR$(29);
  135. GOTO DoCRKey
  136. DoControlKey:
  137.     ' Control character 
  138.     COLOR 15
  139.     PRINT CHR$(KeyCode + 64);
  140.     COLOR 7
  141. DoCRKey:
  142.     ' \ = <CR>
  143.     IF KeyCode = 92 THEN Text$ = Text$ + CHR$(13) :            _
  144.        GOTO InKey
  145.     ' Add & get more
  146.     Text$ = Text$ + CHR$(KeyCode)
  147. GOTO InKey
  148.  
  149. ' GetKeyxxxx
  150. ' A fall-through series of input utility subroutines
  151. ' Prompt the user to press a key (handy for user-released pauses)
  152. GetKeyPress:
  153.     LOCATE 25 , 71 
  154.     PRINT "KEYPRESS";
  155.     GOTO GetKeyLoop
  156. ' Clear the keyboard buffer (sometimes you want no accidental response)
  157. GetKeyClear:
  158.     WHILE INKEY$ <> ""
  159.     WEND                ' Falls through to GetKeyLoop
  160.  
  161.  
  162. ' Get the key input (coming directly here allows reading keyboard buffer).
  163. GetKeyLoop:
  164.     '|    Temp$ = one ASCII character, capitalized, if alpha.
  165.     Temp$ = INKEY$
  166.     IF Temp$ = ""                            _
  167.        THEN GOTO GetKeyLoop
  168.  
  169. ' You can come in here with a full Temp$ 
  170. GetUpperCase:
  171.     Num = 1
  172.     WHILE Num <= LEN(Temp$)
  173.           KeyCode = ASC(MID$(Temp$ , Num , 1))
  174.           KeyCode = KeyCode + 32 * (KeyCode > 96 AND KeyCode < 123)
  175.           MID$(Temp$ , Num , 1) = CHR$(KeyCode)
  176.           Num = Num + 1
  177.     WEND
  178. RETURN
  179.  
  180.  
  181.     '| Get a character from the keyboard, then determine the 
  182.     '|  ASCII key code (KeyCode) & set the extended code flag (IsExtended).
  183.     '|  Input: Temp$ = one character from an INKEYS query
  184.     '|  Returns:
  185.     '|    KeyCode = ASCII key code
  186.     '|    IsExtended = True if extended code else IsExtended = False
  187. GetKeyCode: 
  188.     Temp$ = INKEY$
  189.     IF Temp$ = ""                            _
  190.        THEN GOTO GetKeyCode
  191.  
  192.     ' If you already have an INKEY$ in Temp$, you can start right here
  193. GetCode:
  194.     IF LEFT$(Temp$ , 1) = CHR$(0)                    _
  195.        THEN Temp$ = MID$(Temp$ , 2) :                _
  196.         IsExtended = 1                         _
  197.         ELSE IsExtended = 0
  198.     KeyCode = ASC(Temp$)
  199.     LOCATE , , 0
  200. RETURN
  201.  
  202.  
  203.     ' Hardware INdependent timer routine requires Dly = time in seconds
  204.     '  to delay -- this can be a decimal fraction for very short delays.
  205.     '  The shortest possible effective setting is Dly = .05 seconds.
  206.     ' NOTE: If you are using DEFINT and it includes variables starting
  207.     '        with `D', you must declare DEFSNG D, else these won't work
  208.     '        with times less than a second.
  209.     '       The simpler, SOUND 32767 , Dly doesn't work on my Leading
  210.     '        Edge (Early XT clone). Dunno why.
  211.  
  212.     ' Need to isolate Dly, so it can then continue to be used
  213.     '  when you want to return here for the same delay time.
  214.     ' >>> Watch using D in main program -- gets to be a big number here.
  215. Delay:
  216.     D = 0
  217.     D = Dly + TIMER
  218.         WHILE D > TIMER
  219.     WEND
  220.     D = 0
  221. RETURN
  222.  
  223.  
  224. '| Screen centering:
  225. '| Enter with Text$ containing the string to be centered
  226. '| Three 80-column width subroutines:
  227. '|        Center uses TAB and does a <CR> -- best when you aren't
  228. '|                     in control of CSRLIN and not changing colors.
  229. '|
  230. '|        CenterStay uses TAB and stays on that line -- best for 
  231. '|               input requests and not changing colors.
  232. '|
  233. '|        CenterPoint uses LOCATE & CSRLIN, staying on the line --
  234. '|               most useful for changing colors in the line, but
  235. '|               requires careful control via CSRLIN.    
  236.  
  237. '    ________________________ CENTERING SUBROUTINES _______________________
  238.  
  239.     ' Center Text$ via TAB and go to next line
  240. Center:
  241.     PRINT TAB(40 - (LEN(Text$) / 2)) Text$
  242. RETURN
  243.  
  244.  
  245.     ' Center Text$ via TAB and remain at its end
  246. CenterStay:
  247.     PRINT TAB(40 - (LEN(Text$) / 2)) Text$;
  248. RETURN
  249.  
  250.  
  251.     ' Center Text$ via LOCATE command and remain at its end
  252. CenterPoint:
  253.     LOCATE CSRLIN + 1 , 40 - (LEN(Text$) / 2)
  254.     PRINT Text$; 
  255. RETURN
  256.  
  257.  
  258. '  _____________________ SCREEN CLEARING SUBROUTINES ____________________
  259.  
  260. '| Reverse screen clearing:
  261. '| SCREEN.SUB contains subroutines only for reverse screen clearing because
  262. '|  forward screen clearing is an easy programming task.
  263. '|
  264. '| Enter with Num = the number of lines to clear from the current line upward.
  265. '| Also, there is provision to use a time delay to control the speed of screen 
  266. '|  erasure. You must set Dly = 0 if you want no delay in screen clearing.
  267. '|  >> This Dly is not factored for seconds -- it is a raw number for a 
  268. '|  timing loop; thus it can be set for faster loops than the usual Dly would
  269. '|  produce -- experiment with this ( I usually set Dly = 0). By the way,
  270. '|  the subroutines actually print spaces to clear the required points.
  271. '| If you fail to set Dly, the routine will accept a previously set variable.
  272. '|  This is highly likely if you are using the Delay subroutine, which is
  273. '|  contained in this file. Best to habitually use Dly = 0 before entering.
  274. '| Two reverse clear subroutines:
  275. '|        ClearIn clears from the current line up, working from
  276. '|            the edges of the screen into the center.
  277. '|        ClearOut clears from the current line, working from
  278. '|             the center of the screen to the edges.
  279.  
  280.     'Clear the screen from current position back for Num lines,
  281.     ' working from the center out.
  282. ClearOut:
  283.     RelX = CSRLIN
  284.     RelY = 40
  285.     FOR X = 0 TO Num
  286.         FOR Y = 0 TO 39
  287.         LOCATE RelX - X , RelY + Y + 1 , 0
  288.         PRINT " ";
  289.         LOCATE RelX - X , RelY - Y
  290.         PRINT " ";
  291.         FOR Temp = 0 TO Dly : NEXT Temp
  292.         NEXT Y
  293.     NEXT X
  294. RETURN
  295.  
  296.  
  297.     'Clear the screen from current position back for Num lines,
  298.     ' working from the edges in.
  299. ClearIn:
  300.     RelX = CSRLIN
  301.     RelY = 40
  302.     FOR X = 0 TO Num
  303.         FOR Y = 39 TO 0 STEP -1
  304.         LOCATE RelX - X , RelY + Y + 1 , 0
  305.         PRINT " ";
  306.         LOCATE RelX - X , RelY - Y
  307.         PRINT " ";
  308.         FOR Temp = 0 TO Dly : NEXT Temp
  309.         NEXT Y
  310.     NEXT X
  311. RETURN
  312.  
  313.  
  314.     ' Prints a hatched background to guide input
  315.     ' Input: FG , RelX , RelY , KeyMax = allowed length of input
  316. Hatch:
  317.     PRINT STRING$(KeyMax , 176);
  318.     LOCATE RelX , RelY 
  319.     COLOR FG + 16 , MG
  320.     PRINT CHR$(95); CHR$(29);
  321.     COLOR FG
  322. RETURN
  323.  
  324.  
  325. '    _____________________ Sign PRINTING SUBROUTINES ____________________
  326.  
  327.     ' Show Text$ at a point previously set by the LOCATE n , n comand.
  328.     ' That corner will be the upper left corner of a sign looking like:
  329.     '
  330.     '        *******************************
  331.         '               ** This is the text in Text$ **
  332.     '            *******************************
  333.     '
  334.     ' The border will be the ASCII character input as KeyCode.
  335.     ' You can specify the colors FG, BG, & MG -- these variables are
  336.     ' typically used by other subroutines to set foreground color, back-
  337.     ' ground color, and margin color respectively. In this subroutine, the
  338.     ' screen margin will not be altered, and MG will be the color to use
  339.     ' for the ASCII character margin built around Text$. X,Y is top left.
  340. Sign:
  341.     'Read color attributes for restoration after printing strings
  342.     RelX = X
  343.     RelY = Y
  344.     GOSUB ReadScreen
  345.     LOCATE X , Y , 0
  346.     COLOR MG , BG
  347.     PRINT STRING$(LEN(Text$) + 6 , KeyCode);
  348.     LOCATE X + 1 , Y
  349.     PRINT CHR$(KeyCode); CHR$(KeyCode); " ";
  350.     COLOR FG , BG
  351.     PRINT Text$;
  352.     COLOR MG , BG
  353.     PRINT " "; CHR$(KeyCode); CHR$(KeyCode);
  354.     LOCATE X + 2 , Y
  355.     PRINT STRING$(LEN(Text$) + 6 , KeyCode);
  356.     COLOR HoldFG , HoldBG
  357.     LOCATE , , 1
  358. RETURN
  359.  
  360.  
  361.     ' Show Text$ centered on current line, looking like: 
  362.     '
  363.     '        ***************************
  364.         '                This is the text in Text$
  365.     '            ***************************
  366.     '
  367.     ' The border is the ASCII character input as the variable, KeyCode.
  368.     ' Color use is identical to Sign, but notice this subroutine does
  369.     '  not frame Text$ horizontally.
  370. SignCenter:
  371.     'Read color attributes for restoration after printing strings
  372.     IF NOT Y THEN Y = 1
  373.     RelX = X
  374.     RelY = Y
  375.     GOSUB ReadScreen
  376.     ' Print the top frame
  377.     LOCATE X , 39 - (LEN(Text$) / 2) , 0
  378.     COLOR MG , BG
  379.      PRINT STRING$(LEN(Text$) + 2 , KeyCode);
  380.     ' Print Text$
  381.     COLOR FG , BG
  382.     LOCATE X + 1 ,  39 - (LEN(Text$) / 2) 
  383.     PRINT " ";Text$;" ";
  384.     ' Print the bottom frame
  385.     LOCATE X + 2 ,  39 - (LEN(Text$) / 2) 
  386.     COLOR MG , BG
  387.      PRINT STRING$(LEN(Text$) + 2 , KeyCode);
  388.     COLOR HoldFG , HoldBG
  389.     LOCATE , , 1
  390. RETURN
  391.  
  392.  
  393.     ' Subroutine to highlight the first character of each word
  394.     '  in a string of words contained in Text$.
  395.     ' Primarily used to provide a first-letter prompt string.
  396.     ' Input:
  397.     '    The colors Glow, FG, BG, MG
  398.     '    The string of words Text$
  399.     '    The X & Y location to print Text$
  400.     'This subroutine adds a leading space to Text$, so you may
  401.     ' need to adjust the Y variable accordingly. 
  402. Glow:
  403.     LOCATE X , Y
  404.     COLOR Glow
  405.     PRINT " ";LEFT$(Text$ , 1);
  406.     COLOR FG
  407.     FOR Num = 2 TO LEN(Text$)
  408.         Temp$ = MID$(Text$ , Num , 1)
  409.         PRINT Temp$;
  410.         IF ASC(Temp$) = 32                        _
  411.            THEN COLOR Glow                        _
  412.            ELSE COLOR FG
  413.     NEXT Num
  414. RETURN
  415.  
  416.  
  417.     'Read color attributes for restoration after printing strings
  418.     'Input: RelX, RelY = target row & column 
  419.     'Output: HoldFG = current foreground, HoldBG = current background
  420. ReadScreen:
  421.     ' Read foreground color
  422.     HoldFG = ((SCREEN (RelX , RelY , 1)) MOD 16)
  423.     ' Read background color
  424.     HoldBG = (((SCREEN (RelX , RelY , 1)) - HoldFG) / 16) MOD 128
  425. RETURN
  426. ' >>>>> Physical EOF OMNI.SUB  25 June 86
  427.